10장. 결합 균형

출처: 『소프트웨어 설계의 결합 균형』(블라드 코노노프 지음, 장연호 옮김, 제이펍 2026) | 공식: https://www.jpub.kr/

한 줄 요약: 설계의 목표는 결합 강도를 최소화하는 것이 아니라 모듈식 시스템을 만드는 것이다. 강도·거리·변동성 세 축을 동시에 보고 균형점을 찾아야 하며, 강하게 결합해도 되는 것은 가깝고 안정적인 것뿐이다.


학습 목표

이 장을 끝내면 다음을 할 수 있다.

  • 결합의 세 차원(강도·거리·변동성)을 구분하고 각각이 설계에 미치는 영향을 설명한다.
  • 안정성·변경 비용·모듈성·복잡성을 이진 논리식(XOR, AND, NOT)으로 표현한다.
  • 강도×거리 조합의 네 가지 결과(높은 응집력·느슨한 결합·지역 복잡성·전역 복잡성)를 분류한다.
  • BALANCE = max(|STRENGTH - DISTANCE|, 10 - VOLATILITY) + 1 공식을 실제 시나리오에 적용한다.
  • 복잡성 + 높은 변동성이 왜 가장 위험한 조합인지 설명한다.
  • 낮은 변동성이 어떻게 높은 강도 또는 먼 거리가 만드는 복잡성을 상쇄하는지 설명한다.

전체 흐름도

                     결합의 세 축 (3D 큐브)
                          변동성(V)
                           높음 ↑
                            │
             ───────────────┼─────────────────
        가까움              │               멀리 (D)
   ←────────────────────────┼────────────────→
             높은 응집력    │    전역 복잡성
          (강도↑ + 거리가까움)  (강도↑ + 거리멀다)
                            │
          지역 복잡성        │    느슨한 결합
          (강도↓ + 거리가까움)  (강도↓ + 거리멀다)
             ───────────────┼─────────────────
                            │     (S=강도)
                           낮음 ↓

  균형 공식 (이진):
  BALANCE = (STRENGTH XOR DISTANCE) OR NOT VOLATILITY
            = 모듈성이거나, 변동성이 낮거나, 둘 다

  균형 공식 (숫자 척도 1~10):
  BALANCE = max(|STRENGTH - DISTANCE|, 10 - VOLATILITY) + 1

  ■ 강도↑ + 거리가까움 = 높은 응집력 → 같이 변하면 가깝게 두어라
  ■ 강도↓ + 거리멀다  = 느슨한 결합  → 분리해야 하면 약하게 연결하라
  ■ 강도↑ + 거리멀다  = 전역 복잡성  → 최악의 조합
  ■ 강도↓ + 거리가까움 = 지역 복잡성  → 관련 없는 것을 억지로 묶음

0. 사전 필수 용어

용어 설명
통합 강도 (Integration Strength) 두 구성요소가 얼마나 많은 지식을 공유하는가. 계약 결합(낮음)~침입 결합(높음) 스펙트럼. (7~9장)
거리 (Distance) 두 구성요소가 물리적으로 얼마나 멀리 배치됐는가. 같은 메서드 내(1) ~ 다른 회사 시스템(10).
변동성 (Volatility) 상위 구성요소가 얼마나 자주 바뀌는가. 레거시 불변(1) ~ 핵심 하위 도메인(10).
모듈성 (Modularity) 구현·진화·유지 관리가 간단한 설계 속성. 복잡성의 반대.
안정성 (Stability) 연쇄 변경이 발생할 가능성이 낮은 상태. 변동성이나 강도 중 하나가 낮으면 달성.
이진 척도 이 장에서 개념 설명에 사용하는 단순 척도: 높음(1) / 낮음(0).
XOR(배타적 OR) 둘 중 하나만 참일 때 참. 강도와 거리가 서로 반대 값을 가질 때 모듈성 달성.
상위/하위 모듈 지식을 노출하는 쪽이 상위(upstream), 소비하는 쪽이 하위(downstream). 지식 흐름은 의존성 방향의 반대.

1. 왜 세 차원을 함께 봐야 하는가

1~9장에서 강도(strength)·거리(distance)·변동성(volatility)을 각각 배웠다. 10장의 메시지는 단순하고 강력하다.

세 차원 중 어느 하나가 가장 중요하다고 말할 수 없다. 세 가지 모두 함께 관리해야 한다.

목표는 결합 강도를 최소화하는 것이 아니다. 에릭 에번스(Eric Evans)가 말했듯이, 일부 구성요소는 다른 구성요소보다 비즈니스적으로 더 중요하며 더 고급 엔지니어링 도구가 필요하다. 효능에는 건전한 실용주의가 필요하다. 목표는 모듈식 시스템 — 구현·진화·유지 관리가 간단한 시스템 — 을 설계하는 것이다. 이는 세 차원을 동시에 고려할 때만 달성된다.

비유 — 사람 관계로 보는 세 차원

관계 강도 거리 변동성 결과
부부 (같은 집) 높음 가까움 낮음(서로 잘 앎) 높은 응집력 — OK
직장 동료 (같은 팀) 중간 가까움 중간 관리 필요
외부 협력사 낮음 멀다 높음 느슨한 결합 — 약한 계약만
모르는 타회사 높음 멀다 높음 전역 복잡성 — 최악

부부는 강하게 결합돼도 된다 — 가깝고(같은 집), 안정적(서로를 잘 앎). 하지만 모르는 사람과 강하게 결합되면 — 멀고 + 변동성 높음 — 재앙이 된다.

비유 — 건축

같은 집 안의 가구는 강하게 배치해도 된다(가깝고, 주인의 취향이 안정적이면). 하지만 옆 건물과 내 집 벽을 강하게 고정하면 — 옆 건물이 공사를 시작하면 내 벽도 무너진다. 옆 건물과는 약한 연결(출입문, 계약)만 있어야 한다.

소프트웨어도 같다. 같은 네임스페이스의 두 클래스는 강하게 결합돼도 된다(가깝고, 변동이 함께 일어남). 다른 회사 시스템과 강하게 결합하면 — 상대가 API 하나 바꿀 때마다 내 시스템이 흔들린다.


2. 차원 쌍별 상호작용

2.1 안정성: 변동성 × 강도

STABILITY = NOT (VOLATILITY AND STRENGTH)

변동성과 강도 둘 다 높을 때만 불안정하다. 둘 중 하나가 낮으면 안정적이다.

변동성 강도 안정성 이유
낮음 낮음 안정적 변경도 없고, 전파도 안 됨
낮음 높음 안정적 바뀔 일이 없으므로 강도는 문제 아님
높음 낮음 안정적 자주 바뀌지만, 낮은 강도가 전파 차단
높음 높음 불안정 자주 바뀌고, 전파도 잘 됨

비유 — 전화선과 진동: 강도는 전화선의 굵기, 변동성은 전화선 양쪽에서 발생하는 지진의 빈도다. 선이 굵을수록 진동이 잘 전달된다. 진동이 드물면 굵은 선도 별 문제 없다. 진동이 잦고 선도 굵으면 — 맞은편이 흔들릴 때마다 내 쪽도 흔들린다.

2.2 실제 변경 비용: 변동성 × 거리

CHANGES COST = VOLATILITY AND DISTANCE

변동성과 거리 둘 다 높을 때 실제 비용이 최대가 된다.

변동성 거리 변경 비용 이유
낮음 가까움 낮음 둘 다 낮음
낮음 멀다 낮음 자주 안 바뀌므로
높음 가까움 낮음 가깝게 두었으므로 조정 쉬움
높음 멀다 높음 자주 바뀌고, 멀리 있는 팀과 협업해야 함

비유 — 택배와 이삿짐: 이삿짐이 자주 바뀌지 않으면(낮은 변동성) 창고가 멀어도 큰 문제 없다. 이삿짐이 매일 바뀌는데 창고가 서울-부산 거리면 — 매일 택배비와 배송 시간이 든다. 변동성을 낮추거나 창고를 가까이 두거나, 둘 중 하나로 해결해야 한다.

2.3 모듈성과 복잡성: 강도 × 거리

이 조합이 책의 핵심 통찰이다.

MODULARITY = STRENGTH XOR DISTANCE
COMPLEXITY = NOT MODULARITY = NOT (STRENGTH XOR DISTANCE)
LOCAL COMPLEXITY  = NOT STRENGTH AND NOT DISTANCE
GLOBAL COMPLEXITY = STRENGTH AND DISTANCE

강도와 거리가 반대 값일 때 모듈성이 달성된다.

강도 거리 결과 비고
낮음 가까움 지역 복잡성 관련 없는 것을 가까이 묶음
높음 가까움 높은 응집력 같이 변하는 것이 가까이 있음
낮음 멀다 느슨한 결합 분리된 것끼리 약하게 연결
높음 멀다 전역 복잡성 멀리 있는데 강하게 결합 — 최악

핵심 통찰: 강도와 거리는 짝꿍이어야 한다. 강하게 결합할 거면 가까이 두어라. 멀리 떼어 놓을 거면 약하게 연결하라. 두 값이 같을 때(둘 다 높거나 둘 다 낮을 때) 복잡성으로 기운다.


3. 코드 예제

잘못된 예 — 전역 복잡성 (강도↑ + 거리↑)

# WolfDesk 사례: 두 마이크로서비스(거리=9)에 동일한 비즈니스 로직 복제 (대칭적 기능 결합=9)
# 잘못된 예: 분산 서비스에 핵심 비즈니스 로직을 직접 복제

# support_cases_service/escalation.py
def can_escalate(case):
    return case.priority >= 3 and case.age_hours >= 24  # 비즈니스 규칙

# distribution_service/escalation.py (다른 서비스에 복제!)
def can_escalate(case):
    return case.priority >= 3 and case.age_hours >= 24  # 동일 규칙 복제

# 문제: 규칙 변경 시 두 서비스를 동시에 업데이트해야 함
# 강도(9) × 거리(9) → 전역 복잡성, BALANCE = max(|9-9|, 10-10)+1 = 1 (최악)

올바른 예 — 느슨한 결합 (강도↓ + 거리↑)

# 올바른 예: 비즈니스 규칙을 한 서비스에 두고, 계약(API)으로만 연결
# support_cases_service/api.py
@app.get("/cases/{case_id}/can-escalate")
def can_escalate_endpoint(case_id: str):
    case = case_repo.get(case_id)
    return {"result": case.priority >= 3 and case.age_hours >= 24}

# distribution_service/client.py
class EscalationClient:
    def can_escalate(self, case_id: str) -> bool:
        return requests.get(f"{BASE_URL}/cases/{case_id}/can-escalate").json()["result"]

# 거리(9)이지만 강도(1=계약 결합) → BALANCE = max(|1-9|, 10-10)+1 = max(8,0)+1 = 9 (거의 최상)

올바른 예 — 높은 응집력 (강도↑ + 거리↓)

# 같은 네임스페이스 안에서 강하게 결합 — 거리가 가깝기 때문에 OK
# support_cases_service/models.py

class SupportCase:
    def __init__(self, case_id, priority, age_hours):
        self.case_id = case_id
        self.priority = priority
        self.age_hours = age_hours

class Message:
    def __init__(self, case: SupportCase, content: str):
        self.case = case  # 강한 기능 결합(8) — 같은 트랜잭션 필요
        self.content = content

    def save_with_case(self, session):
        session.add(self.case)  # 같은 트랜잭션 커밋
        session.add(self)
        session.commit()

# 강도(8) × 거리(2=같은 네임스페이스) → 높은 응집력
# BALANCE = max(|8-2|, 10-10)+1 = max(6,0)+1 = 7 (양호)

잘못된 예 — 변동성 높은 상위에 강하게 결합

# 잘못된 예: 자주 바뀌는 핵심 비즈니스 로직(변동성=10)을 다른 팀 서비스(거리=8)가 모델 공유
# billing_service/client.py
from support_cases_service.models import SupportCase  # 내부 모델 직접 임포트

class BillingService:
    def calculate_fee(self, case: SupportCase) -> float:
        return case.priority * case.age_hours * 0.01  # SupportCase 내부 필드를 직접 사용

# 문제: SupportCase 내부 구조가 바뀌면(핵심 하위 도메인이라 자주 바뀜) BillingService도 깨짐
# 강도(7=모델 결합) + 거리(8=다른 라이브러리) + 변동성(10) → BALANCE 낮음

올바른 예 — 계약 결합으로 내부 모델 캡슐화

# 올바른 예: 계약(API)으로만 연결 — 내부 모델을 외부에 노출하지 않음
# support_cases_service/api.py
@app.get("/cases/{case_id}/billing-info")
def get_billing_info(case_id: str):
    case = case_repo.get(case_id)
    # 외부에 필요한 것만, 내부 구조는 숨김
    return {"priority": case.priority, "age_hours": case.age_hours}

# billing_service/client.py
class BillingClient:
    def get_billing_info(self, case_id: str) -> dict:
        return requests.get(f"{BASE_URL}/cases/{case_id}/billing-info").json()

class BillingService:
    def calculate_fee(self, case_id: str) -> float:
        info = self.client.get_billing_info(case_id)
        return info["priority"] * info["age_hours"] * 0.01

# 강도(1=계약 결합) + 거리(8) → |1-8|=7 → BALANCE 높음

4. 세 차원을 모두 합치기 — 균형 방정식

4.1 유지 관리 노력

MAINTENANCE EFFORT = STRENGTH × DISTANCE × VOLATILITY

세 차원의 곱이 유지 관리 고통을 나타낸다. 하나라도 0이면 전체가 0이 된다 — 하나만 낮게 유지하면 나머지가 높아도 된다.

시나리오 강도 거리 변동성 유지 관리 노력
느슨한 결합 낮음 멀다 높음 낮음 (강도가 0을 만듦)
높은 응집력 높음 가까움 높음 낮음 (거리가 0을 만듦)
레거시 통합 높음 멀다 낮음 낮음 (변동성이 0을 만듦)
최악 높음 멀다 높음 높음 (세 곱이 모두 높음)

주의: 유지 관리 노력 공식은 더 높은 수준의 사각지대가 있다. 낮은 강도 + 가까운 거리 + 높은 변동성 조합에서 지역 복잡성의 문제를 포착하지 못한다. 이를 위해 균형 잡힌 결합 개념이 필요하다.

4.2 균형 잡힌 결합

두 가지 나쁜 조합이 있다.

전역 복잡성 + 높은 변동성: 강도↑ + 거리↑ + 변동성↑  ← 최악
지역 복잡성 + 높은 변동성: 강도↓ + 거리가까움 + 변동성↑ ← 나쁨

이진 논리로 균형을 표현하면:

BALANCE = NOT (COMPLEXITY AND VOLATILITY)
        = MODULARITY OR NOT VOLATILITY
        = (STRENGTH XOR DISTANCE) OR NOT VOLATILITY

풀어 읽기: 균형은 모듈성이 있거나, 변동성이 낮거나, 둘 중 하나이면 된다. 복잡성 + 높은 변동성이 동시에 존재할 때만 진짜 위험하다.

4.3 숫자 척도로 균형 계산

책이 제안하는 임의 척도 (1~10):

차원 1 10
통합 강도 계약 결합 침입 결합
거리 같은 객체 메서드 다른 회사 시스템
변동성 진화 없는 레거시 핵심 하위 도메인

거리 세부 기준: - 1: 동일한 객체의 메서드 - 2: 동일한 네임스페이스/패키지의 객체 - 3~7: 다른 네임스페이스/패키지의 객체 - 8: 다른 라이브러리 - 9: 분산 시스템의 서비스 - 10: 다른 공급업체가 구현한 시스템

모듈성 점수: MODULARITY = |STRENGTH - DISTANCE| + 1 강도와 거리의 차이가 클수록(서로 반대 값일수록) 모듈성이 높다.

균형 점수: BALANCE = max(|STRENGTH - DISTANCE|, 10 - VOLATILITY) + 1 모듈성이 낮더라도 변동성이 충분히 낮으면 균형이 높아진다. 낮은 변동성이 복잡성을 상쇄한다.

주의사항: 이것은 정확한 과학이 아니다. 책 저자 본인이 강조한다. 척도와 범위는 팀에 맞게 조정하라. 중요한 것은 숫자 자체가 아니라 세 차원이 어떻게 함께 작동하는지 이해하는 것이다.


5. 실제 시나리오 4가지 — WolfDesk 예제

예제 1: ML 서비스 통합 (균형 점수 8 → 10)

WolfDesk의 Support Cases Management(핵심 하위 도메인)가 외부 클라우드 ML 서비스에 운영 DB 데이터를 직접 공급하는 경우.

강도(S) = 3  (모델 결합 — DB 스키마 공유)
거리(D) = 10 (다른 회사 시스템)
변동성(V) = 10 (핵심 하위 도메인)

BALANCE = max(|3-10|, 10-10) + 1
        = max(7, 0) + 1 = 8

계약 결합(S=1)으로 개선하면:
BALANCE = max(|1-10|, 10-10) + 1 = max(9, 0) + 1 = 10 (완벽)

교훈: 거리가 멀수록 강도를 더 낮춰야 균형 점수가 올라간다.

예제 2: 같은 모듈 내 두 객체 (균형 점수 7)

Support Cases Management 안의 SupportCase와 Message — 같은 트랜잭션 커밋 필요.

강도(S) = 8  (기능 결합 — 트랜잭션 공유)
거리(D) = 2  (같은 네임스페이스)
변동성(V) = 10 (핵심 하위 도메인)

BALANCE = max(|8-2|, 10-10) + 1
        = max(6, 0) + 1 = 7

→ 양호. 강도가 높지만 거리가 가깝기 때문에 균형.

교훈: 비즈니스 요구상 강하게 결합해야 한다면, 가까이 두어라(높은 응집력).

예제 3: 마이크로서비스 간 비즈니스 로직 복제 (균형 점수 1 — 최악)

두 서비스에 동일한 에스컬레이션 규칙을 복제.

강도(S) = 9  (대칭적 기능 결합 — 동일 알고리즘 복제)
거리(D) = 9  (분산 시스템의 두 서비스)
변동성(V) = 10 (핵심 하위 도메인)

BALANCE = max(|9-9|, 10-10) + 1
        = max(0, 0) + 1 = 1 (최악)

교훈: 강도 = 거리인 경우 모듈성이 0이 된다. 복잡성 + 높은 변동성 = 최악의 조합.

예제 4: 레거시 시스템 침입 통합 (균형 점수 10)

새 마이크로서비스가 레거시 시스템의 DB에 직접 접근 — 하지만 레거시는 더 이상 변경되지 않는다.

강도(S) = 10 (침입 결합 — 비공개 인터페이스 접근)
거리(D) = 9  (같은 회사의 다른 시스템)
변동성(V) = 1 (진화하지 않는 레거시)

BALANCE = max(|10-9|, 10-1) + 1
        = max(1, 9) + 1 = 10 (완벽)

교훈: 낮은 변동성이 높은 강도와 먼 거리를 완전히 상쇄한다. "항상 강한 결합은 나쁘다"가 아니다 — 상위가 변하지 않으면 강하게 의존해도 유지 관리 비용이 낮다.


6. 안티패턴

안티패턴 1: 전역 복잡성 + 높은 변동성 (최악)

강도↑ + 거리↑ + 변동성↑

신호:
- 자주 바뀌는 핵심 비즈니스 로직을 다른 회사/팀 서비스와 강하게 결합
- 마이크로서비스 간 DB 직접 공유 + 해당 스키마가 자주 변경됨
- 외부 파트너와 내부 구현 세부(침입 결합)로 통합

처방: 계약 결합(강도↓)으로 바꾸거나, 상위를 안정화(변동성↓)하거나, 가까이 배치(거리↓)하라.

안티패턴 2: 지역 복잡성 + 높은 변동성

강도↓ + 거리가까움 + 변동성↑

신호:
- 서로 관련 없는 기능이 같은 클래스/패키지에 모여 있음
- 파일이 자주 바뀌는데 그 안에 연관 없는 코드가 섞여 있음
- "한 파일에 다 넣어 두는" 스타일

처방: 관련 없는 구성요소를 분리하라(거리↑). 가까이 있어야 하는 것만 가까이 두어라.

7. 실무 결정 매트릭스

상황 권장 전략 이유
같은 팀, 같은 배포, 함께 변경 강하게 결합 + 가깝게 배치 높은 응집력 — 자연스러운 공생
다른 팀, 자주 변경되는 상위 계약 결합(약하게) + 멀리 느슨한 결합 — 변경 격리
외부 파트너, 안정적(변경 없음) 강도 타협 가능 낮은 변동성이 강도 상쇄
레거시 통합(불변) 침입도 OK 변동성=1이 모든 걸 상쇄
핵심 하위 도메인 간 분리 반드시 계약 결합 양쪽 모두 변동성 높아 위험

핵심 개념 정리

개념 한 줄 설명
결합의 세 차원 강도(얼마나 많이 앎) + 거리(얼마나 멀리) + 변동성(얼마나 자주 변함)
안정성 NOT (VOLATILITY AND STRENGTH) — 둘 중 하나만 낮아도 안정
변경 비용 VOLATILITY AND DISTANCE — 둘 다 높을 때만 비쌈
모듈성 STRENGTH XOR DISTANCE — 서로 반대 값일 때 달성
균형 (이진) (STRENGTH XOR DISTANCE) OR NOT VOLATILITY
균형 (숫자) BALANCE = max(|S-D|, 10-V) + 1 (1~10 척도)
높은 응집력 강도↑ + 거리가까움 — 같이 변할 것을 가까이 둠
느슨한 결합 강도↓ + 거리멀다 — 분리된 것끼리 약하게 연결
전역 복잡성 강도↑ + 거리↑ — 가장 위험한 조합
지역 복잡성 강도↓ + 거리가까움 — 관련 없는 것을 강제로 묶음
유지 관리 노력 STRENGTH × DISTANCE × VOLATILITY — 하나만 0이면 전체 0
낮은 변동성의 힘 복잡성도 상쇄 가능 — 레거시 침입 통합 예제
에릭 에번스의 실용주의 목표는 강도 최소화가 아닌 모듈식 시스템 — 건전한 실용주의 필요

실무 체크리스트

  • [ ] 새 통합을 설계할 때 강도·거리·변동성 세 가지 모두를 명시적으로 평가했는가?
  • [ ] 강도가 높다면 거리가 가까운가? (높은 응집력 보장)
  • [ ] 거리가 멀다면 강도가 낮은가? (느슨한 결합 보장)
  • [ ] 변동성이 높은 상위에 강하게 결합하고 있지 않은가? (안정성 확인)
  • [ ] 외부 파트너나 다른 팀 서비스와 통합할 때 계약 결합을 사용하고 있는가?
  • [ ] 레거시 시스템 통합 시 변동성을 먼저 평가했는가? (낮으면 강도 타협 가능)
  • [ ] 마이크로서비스 간에 동일한 비즈니스 로직을 복제하고 있지 않은가? (대칭적 기능 결합 경고)
  • [ ] BALANCE = max(|S-D|, 10-V) + 1 점수가 낮은 통합을 식별하고 개선 계획이 있는가?
  • [ ] "강도를 무조건 낮추자"가 목표가 아니라 "모듈식 시스템"이 목표임을 팀이 공유하고 있는가?
  • [ ] 유지 관리 노력 공식의 사각지대(지역 복잡성)도 별도로 점검했는가?

연습문제 (정답은 부록 D)

  1. 공식 적용. 다음 시나리오의 균형 점수를 계산하라. 강도=5(모델 결합), 거리=5(다른 패키지의 서비스), 변동성=8(핵심 하위 도메인에 가까운 기능). 이 설계를 어떻게 개선할 수 있는가?

  2. 분류. 다음 네 가지 조합을 "높은 응집력 / 느슨한 결합 / 지역 복잡성 / 전역 복잡성" 중 하나로 분류하고, 각각이 왜 모듈성 또는 복잡성에 기여하는지 설명하라.

  3. a. 강도=낮음, 거리=가까움
  4. b. 강도=높음, 거리=가까움
  5. c. 강도=낮음, 거리=멀다
  6. d. 강도=높음, 거리=멀다

  7. 레거시 시나리오. 팀이 레거시 시스템(10년 된 ERP, 더 이상 개발하지 않음)과 통합해야 한다. ERP는 공식 API가 없어 DB에 직접 접근할 수밖에 없다. 이 결합의 균형 점수를 계산하고, 이 방식이 받아들일 만한지 판단하라.

  8. 안티패턴 진단. 현재 팀의 코드베이스에서 "전역 복잡성" 안티패턴의 신호를 세 가지 찾는 방법을 설명하라. 어떤 파일·경로·통합 패턴을 먼저 살펴보겠는가?

  9. 설계 결정. 스타트업이 자사의 핵심 추천 알고리즘(매일 바뀌는 핵심 하위 도메인)을 외부 ML 플랫폼(다른 회사)과 통합하려 한다. 두 가지 방안을 비교하라. a) ML 플랫폼이 내부 DB를 직접 읽음, b) 공식 데이터 내보내기 API를 통해 데이터 공급. 각 방안의 균형 점수를 추정하고 권장 방안을 제시하라.


최신 동향 (검증 2026-05-21)

  • 모듈 모놀리스 재조명: 분산 시스템에서 거리를 늘렸을 때 강도를 낮추지 않아 전역 복잡성이 발생하는 사례가 누적되면서, 모듈 모놀리스(Modular Monolith) — 논리적으로 분리되나 배포는 하나 — 접근법이 재조명받고 있다. Sam Newman이 마이크로서비스 분리 전 모듈 경계를 먼저 정의할 것을 강조한다. samnewman.io
  • 진화적 아키텍처와 피트니스 함수: Neal Ford·Rebecca Parsons 등이 강조하는 핵심 원칙이 "변동성에 맞춰 결합 강도를 적응시키는 것"이다. 피트니스 함수(fitness function)로 결합 지표를 지속 측정해 균형 이탈을 자동 감지하는 방향으로 발전 중이다. evolutionaryarchitecture.io
  • 결합 측정 도구화: 정적 분석 도구들이 모듈 간 의존성 강도와 거리를 자동 측정하는 기능을 강화하고 있다. 저자가 미래에 기대한 자동화 평가 도구가 점진적으로 실현되는 추세다.

부록 A. 용어 사전

한글 용어 원문 영문명 의미
강도 Integration Strength 두 구성요소가 공유하는 지식의 양. 계약 결합(낮음)~침입 결합(높음)
거리 Distance 구성요소 간 물리적 배치 거리. 같은 메서드(1)~다른 회사(10)
변동성 Volatility 상위 구성요소가 변경되는 빈도. 레거시(1)~핵심 하위 도메인(10)
모듈성 Modularity 구현·진화·유지 관리가 간단한 설계 속성
복잡성 Complexity 모듈성의 반대. 지역(강도↓+거리가까움) 또는 전역(강도↑+거리↑)
안정성 Stability 연쇄 변경 가능성이 낮은 상태. NOT(변동성 AND 강도)
균형 Balance 강도·거리·변동성 세 차원의 종합 설계 품질. 1~10 점수
유지 관리 노력 Maintenance Effort 통합 유지에 필요한 예상 노력. 강도×거리×변동성
높은 응집력 High Cohesion 강도↑+거리가까움 — 같이 변할 것이 가까이 있음
느슨한 결합 Loose Coupling 강도↓+거리↑ — 분리된 것끼리 약하게 연결
전역 복잡성 Global Complexity 강도↑+거리↑ — 가장 위험한 결합 조합
지역 복잡성 Local Complexity 강도↓+거리가까움 — 관련 없는 것을 가까이 묶음
XOR Exclusive OR 둘 중 하나만 참일 때 참. 강도와 거리가 반대 값일 때 모듈성
상위 모듈 Upstream Module 지식을 노출하는 쪽. 지식 흐름 방향의 출발점
하위 모듈 Downstream Module 지식을 소비하는 쪽. 상위에 의존하는 소비자

부록 B. 핵심 비교표

강도 × 거리 조합의 네 가지 결과

강도 거리 결과 비유 권장 여부
높음 가까움 높은 응집력 부부 — 강하게 결합, 가까이 삶 권장 (함께 변할 것)
낮음 멀다 느슨한 결합 계약서로만 만나는 파트너 권장 (분리할 것)
낮음 가까움 지역 복잡성 억지로 같은 방에 모인 타인들 비권장 (분리하라)
높음 멀다 전역 복잡성 서울-부산에 사는데 매일 이사 최악 — 반드시 개선

숫자 척도 기준표

통합 강도 거리 변동성
1 계약 결합 같은 객체 메서드 불변 레거시
2~3 모델 결합 같은 네임스페이스 지원 하위 도메인
8~9 기능/대칭 결합 분산 서비스 중요 도메인
10 침입 결합 다른 회사 시스템 핵심 하위 도메인

WolfDesk 예제 균형 점수 요약

예제 강도 거리 변동성 BALANCE 평가
ML 서비스 통합 (모델 결합) 3 10 10 8 양호
ML 서비스 통합 (계약 결합) 1 10 10 10 최상
SupportCase-Message (같은 모듈) 8 2 10 7 양호
마이크로서비스 로직 복제 9 9 10 1 최악
레거시 침입 통합 10 9 1 10 최상 (변동성 덕분)

부록 C. 추천 참고 자료 & 링크

자료 링크
책 공식 (제이펍) jpub.kr
원서 — Manning Balancing Coupling in Software Design
진화적 아키텍처 (Ford·Parsons) evolutionaryarchitecture.io
Sam Newman — Building Microservices 2nd samnewman.io
마이크로서비스 패턴 (Chris Richardson) microservices.io/patterns

책 다른 장 안내

설명
1장 결합의 정의 — 강도의 두 동인(공유 수명주기·공유 지식)
4장 모듈성 — 결합의 반대편
7~9장 통합 강도 모델 (계약~침입 결합 스펙트럼)
11장 시간이 지나도 모듈성 유지하기 — 진화
12장 소프트웨어 설계의 프랙털 기하학

부록 D. 연습문제 풀이

  1. (균형 점수 계산 및 개선) BALANCE = max(|5-5|, 10-8) + 1 = max(0, 2) + 1 = 3. 매우 낮은 점수 — 강도와 거리가 같아 모듈성이 0이고, 변동성도 높다. 개선 방법: ① 강도를 낮춘다(계약 결합 S=1) → max(|1-5|, 2)+1 = max(4,2)+1 = 5. ② 거리를 좁힌다(같은 패키지 D=2) → max(|5-2|, 2)+1 = max(3,2)+1 = 4. 가장 좋은 방법은 강도를 대폭 낮추거나(계약 결합), 변동성을 낮추는 것(안정화 또는 안정적 인터페이스 분리).

  2. (분류)

  3. a. 강도=낮음, 거리=가까움 → 지역 복잡성. 관련 없는 구성요소를 가까이 묶어 탐색 부하 증가. 변경 시 무관한 코드를 살펴봐야 함.
  4. b. 강도=높음, 거리=가까움 → 높은 응집력. 같이 변해야 하는 구성요소가 가까이 있어 변경 구현 비용 낮음. 모듈성에 기여.
  5. c. 강도=낮음, 거리=멀다 → 느슨한 결합. 분리된 구성요소끼리 최소 계약으로 연결. 변경이 전파되지 않아 모듈성에 기여.
  6. d. 강도=높음, 거리=멀다 → 전역 복잡성. 멀리 있는데 강하게 결합 — 변경 전파 비용 최대, 인지 부하 최대. 가장 위험.

  7. (레거시 시나리오) 레거시 ERP는 더 이상 진화하지 않으므로 변동성(V) = 1. DB 직접 접근이므로 강도(S) = 10(침입 결합). 같은 회사 시스템이면 거리(D) = 9. BALANCE = max(|10-9|, 10-1)+1 = max(1, 9)+1 = 10. 받아들일 만하다 — 낮은 변동성(1)이 침입 결합과 먼 거리를 완전히 상쇄한다. 단, 레거시가 언젠가 마이그레이션될 계획이라면 그 시점의 변동성을 다시 평가해야 한다.

  8. (전역 복잡성 신호 찾기) 다음을 먼저 살펴보라: ① 서비스 간 직접 DB 접근 — 다른 서비스의 DB를 직접 SELECT하는 코드. 마이크로서비스라면 절대 없어야 함(강도↑+거리↑). ② 양방향 의존성 — 서비스 A가 B를 호출하고, B도 A를 호출하는 순환 의존. 두 서비스가 서로의 내부를 안다는 신호. ③ 분산 서비스에 복제된 비즈니스 로직 — 동일한 조건식이나 알고리즘이 두 서비스에 복사되어 있음. 한쪽 변경 시 다른 쪽도 바꿔야 하는 대칭적 기능 결합.

  9. (설계 결정 비교) a안: ML 플랫폼이 내부 DB 직접 읽음 — 강도(S)=5(모델 결합), 거리(D)=10(다른 회사), 변동성(V)=10(핵심 알고리즘)BALANCE = max(|5-10|, 10-10)+1 = max(5,0)+1 = 6. 보통. b안: 공식 데이터 내보내기 API — 강도(S)=1(계약 결합), 거리(D)=10, 변동성(V)=10BALANCE = max(|1-10|, 10-10)+1 = max(9,0)+1 = 10. 최상. 권장: b안. 핵심 하위 도메인(변동성=10)의 내부 모델을 외부에 노출하면 알고리즘이 바뀔 때마다 외부 파트너도 영향을 받는다. 계약 결합으로 내부 모델 변경을 캡슐화하는 것이 필수.

난이도
에피소드
질문
카드를 로딩 중...
답변

클릭하거나 Space를 눌러 뒤집기

0 / 0
학습 진도 0%
이동   Space 뒤집기   R 셔플